﻿/*! @file
********************************************************************************
<PRE>
文 件 名    : BaseTransformFactory.cs
说    明    : 转换工厂类
作    者    : 汪泽然
--------------------------------------------------------------------------------
备    注    : 
--------------------------------------------------------------------------------
修改记录: 
 * 日    期     版  本       修改人      修改内容 
 * 2009-7-9     0.5.0       汪泽然      完成基本转换功能
 *                                      添加安全转换，对转换文件进行保护
 * 2009-7-16    0.5.1       汪泽然      【增加属性】目标框架版本
 * 2009-7-21    0.5.2       汪泽然      【修复】修复安全转换，转换失败时，恢复所有已转换的文件
</PRE>
********************************************************************************
* 版权所有(c) 2008 ~ 2009, 汪泽然, 保留所有权利
*******************************************************************************/
using System;
using System.IO;
using System.Collections.Generic;
using Wangzeran.Transform.Core.ITransform;
using Wangzeran.Transform.Core.PlugIn;
using Wangzeran.Transform.Core.Safe;
using Wangzeran.Transform.Core.TransformException;
using Wangzeran.Transform.Core.TransformException.File;

namespace Wangzeran.Transform.Core.Support
{
    /// <summary>
    /// 转换工厂类
    /// </summary>
    /// <remarks>
    /// 插件必须继承该工厂类
    /// </remarks>
    public abstract class BaseTransformFactory : IPlugInInfo
    {

        #region Common Variables

        /// <summary>
        /// 转换的解决方案文件实现类
        /// </summary>
        private BaseSlnFile opSlnFile;
        /// <summary>
        /// 转换项目文件的实现类
        /// </summary>
        private BaseProjFile opProjFile;
        /// <summary>
        /// 转换源代码文件的实现类
        /// </summary>
        private BaseSrcFile opSrcFile;
        /// <summary>
        /// 已转换的文件列表
        /// </summary>
        private IList<string> transformFiles;

        #endregion


        #region Common Properties

        /// <summary>
        /// 获取转换 解决方案文件的实现类
        /// </summary>
        /// <remarks>
        /// 实现类可设置 解决方案文件的实现类
        /// </remarks>
        public BaseSlnFile SlnFile
        {
            protected set
            {
                this.opSlnFile = value;
            }
            get
            {
                return this.opSlnFile;
            }
        }

        /// <summary>
        /// 获取转换 项目文件的实现类
        /// </summary>
        /// <remarks>
        /// 实现类可设置 项目文件的实现类
        /// </remarks>
        public BaseProjFile ProjFile
        {
            protected set
            {
                this.opProjFile = value;
            }
            get
            {
                return this.opProjFile;
            }
        }

        /// <summary>
        /// 获取转换 源代码文件的实现类
        /// </summary>
        /// <remarks>
        /// 实现类可设置 源代码文件的实现类
        /// </remarks>
        public BaseSrcFile SrcFile
        {
            protected set
            {
                this.opSrcFile = value;
            }
            get
            {
                return this.opSrcFile;
            }
        }

        

        #endregion

        /// <summary>
        /// 实例化转换工厂类
        /// </summary>
        public BaseTransformFactory()
        {
            InitFactory();
        }

        /// <summary>
        /// 初始化工厂类
        /// </summary>
        protected abstract void InitFactory();

        /// <summary>
        /// 是否已初始化工厂
        /// </summary>
        /// <returns></returns>
        public bool IsInitFactory()
        {
            if (this.opSlnFile == null ||
                this.opProjFile == null ||
                this.opSrcFile == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// 转换所有文件
        /// </summary>
        /// <param name="filePath">解决方案文件的完整路径</param>
        /// <returns>True: 转换成功 False：转换失败</returns>
        /// <exception cref="TransformFailureException">转换失败的异常</exception>
        /// <exception cref="UnInitTransformFactoryException">未初始化转换工厂的异常</exception>
        public bool Transform(string filePath)
        {
            try
            {
                // 先判断是否已初始化工厂
                if (!IsInitFactory())
                {
                    throw new UnInitTransformFactoryException();
                }

                transformFiles = new List<string>();

                // 转换 解决方案文件
                // 将当前文件加入已转换列表
                BackupFile(filePath);
                opSlnFile.Transform(filePath);

                //SafeTransform(opSlnFile, filePath);

                // 获取 项目文件
                IList<string> lstProj = opSlnFile.GetChildFiles(filePath);

                foreach (string item in lstProj)
                {
                    // 转换 项目文件
                    // 将当前文件加入已转换列表
                    BackupFile(item);
                    opProjFile.Transform(item);

                    //SafeTransform(opProjFile, item);

                    // 获取 源代码文件
                    IList<string> lstSrc = opProjFile.GetChildFiles(item);
                    foreach (string srcItem in lstSrc)
                    {
                        // 转换 源代码文件
                        // 将当前文件加入已转换列表
                        BackupFile(srcItem);
                        opSrcFile.Transform(srcItem);

                        //SafeTransform(opSrcFile, srcItem);
                    }
                }

                // 删除备份文件
                DeleteBackupFile();

                return true;
            }
            catch (TransformFailureException ex)
            {
                // 恢复已转换的文件
                RecoveryFile();
                throw ex;
            }
            catch (BaseException ex)
            {
                // 恢复已转换的文件
                RecoveryFile();
                throw ex;
            }
            catch (Exception ex)
            {
                // 恢复已转换的文件
                RecoveryFile();
                throw new TransformFailureException(filePath, ex.Message);
            }
        }


        #region ITransformPlugIn 成员

        /// <summary>
        /// 插件的作者
        /// </summary>
        public abstract string Author
        {
            get;
        }

        /// <summary>
        /// 插件的版本
        /// </summary>
        public abstract string PlugInVersion
        {
            get;
        }

        /// <summary>
        /// 转换的目标版本
        /// </summary>
        public abstract string TargetIDEVersion
        {
            get;
        }

        /// <summary>
        /// 目标框架版本
        /// </summary>
        public abstract string TargetFrameworkVersion
        {
            get;
        }

        /// <summary>
        /// 目标语言
        /// </summary>
        public abstract string TargetLanguage
        {
            get;
        }

        /// <summary>
        /// 更新日志
        /// </summary>
        public abstract string UpdateLog
        {
            get;
        }


        #endregion


        #region 安全转换机制 v0.1

        /// <summary>
        /// 安全转换
        /// </summary>
        /// <param name="op">负责转换的操作者</param>
        /// <param name="filePath">要转换的文件路径</param>
        /// <remarks>
        /// 在转换前会备份该文件，转换后删除备份的文件，如果出错，则恢复该文件 
        /// </remarks>
        [Obsolete("已实现新的转换机制", true)]
        private void SafeTransform(ITransformFile op, string filePath)
        {
        	try 
        	{
        		SafeSupport.Backup(filePath);
	        	op.Transform(filePath);
	        	SafeSupport.DeleteBackup(filePath);
        	} 
        	catch (BaseException ex)
        	{
        		SafeSupport.Recovery(filePath);
        		throw ex;
        	}
        	catch (Exception ex)
        	{
        		SafeSupport.Recovery(filePath);
        		throw ex;
        	}
        }

        #endregion


        #region 安全转换机制 v0.2

        /// <summary>
        /// 备份文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        private void BackupFile(string filePath)
        {
            try
            {
                SafeSupport.Backup(filePath);
                transformFiles.Add(filePath);
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 删除备份文件
        /// </summary>
        private void DeleteBackupFile()
        {
            try
            {
                foreach (string filePath in transformFiles)
                {
                    try
                    {
                        SafeSupport.DeleteBackup(filePath);
                    }
                    catch
                    {
                        continue;
                    }
                }
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 恢复文件
        /// </summary>
        private void RecoveryFile()
        {
            try
            {
                foreach (string filePath in transformFiles)
                {
                    try
                    {
                        SafeSupport.Recovery(filePath);
                    }
                    catch
                    {
                        continue;
                    }
                }
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }


        #endregion

    }
}
